import 'dart:io';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart' as getx;
import '../models/index.dart';

/// Dio网络服务 - 基础设施层
/// 负责应用的HTTP网络请求，基于 Dio 库
/// 
/// 🎯 核心职责：
/// - 提供标准的HTTP请求能力 (GET, POST, PUT, DELETE等)
/// - 统一的请求/响应拦截器管理
/// - 自动错误处理和重试机制
/// - 请求取消和超时控制
/// - 文件上传/下载支持
/// 
/// ⚠️ 设计原则：
/// - 只负责网络请求，不包含具体业务逻辑
/// - 不应该知道具体的API业务概念
/// - 业务API应该在对应的业务服务中定义
class DioService extends getx.GetxService {
  static DioService get to => getx.Get.find<DioService>();
  
  late Dio _dio;
  
  // ==================== API服务配置 ====================
  
  /// 主要API服务器地址
  static const String apiBaseUrl = 'http://124.71.77.44:2233';
  
  /// API服务器主机名（用于SSL检查等）
  static const String apiHost = '124.71.77.44';
  
  /// API服务器端口
  static const int apiPort = 2233;
  
  /// 备用API地址（如果需要）
  static const String apiUrlFallback = 'https://api.example.com';
  
  // ==================== 网络配置 ====================
  
  /// 默认连接超时时间（毫秒）
  static const int defaultConnectTimeout = 10000;
  
  /// 默认接收超时时间（毫秒）
  static const int defaultReceiveTimeout = 10000;
  
  /// 默认发送超时时间（毫秒）
  static const int defaultSendTimeout = 10000;
  
  /// 用户代理字符串
  static const String defaultUserAgent = 'Flutter-App/1.0.0';
  
  // ==================== DNS服务器 ====================
  
  /// Google公共DNS
  static const String googleDns = '8.8.8.8';
  
  /// 百度公共DNS
  static const String baiduDns = '114.114.114.114';
  
  // ==================== 测试域名 ====================
  
  /// 用于DNS解析测试的域名列表
  static const List<String> testDomains = [
    'baidu.com',
    'google.com',
    'shiguangbiaoju.com',
  ];
  
  // 兼容性别名（保持向后兼容）
  static const String defaultBaseUrl = apiBaseUrl;
  
  // ==================== HTTP请求头常量 ====================
  
  /// HTTP Content-Type 头
  static const String httpHeaderContentType = 'Content-Type';
  
  /// HTTP Accept 头
  static const String httpHeaderAccept = 'Accept';
  
  /// HTTP User-Agent 头
  static const String httpHeaderUserAgent = 'User-Agent';
  
  /// HTTP Authorization 头
  static const String httpHeaderAuthorization = 'Authorization';
  
  /// HTTP X-Request-ID 头
  static const String httpHeaderRequestId = 'X-Request-ID';
  
  /// JSON Content-Type 值
  static const String httpContentTypeJson = 'application/json; charset=utf-8';
  
  /// JSON Accept 值
  static const String httpAcceptJson = 'application/json';
  
  /// Bearer 令牌前缀
  static const String httpBearerPrefix = 'Bearer ';

  // ==================== 错误代码常量 ====================
  
  /// SSL证书错误代码
  static const String errorCodeSsl = 'SSL_ERROR';
  
  /// 未授权状态码
  static const int httpStatusUnauthorized = 401;
  
  /// HTTP状态码范围上限
  static const int httpStatusMaxValid = 600;

  
  // 响应式状态变量
  final _isInitialized = false.obs;
  final _isOnline = true.obs;
  
  // Getters - 同步访问
  bool get isInitialized => _isInitialized.value;
  bool get isOnline => _isOnline.value;
  Dio get dio => _dio;
  
  // Getters - 响应式访问
  getx.RxBool get isInitializedRx => _isInitialized;
  getx.RxBool get isOnlineRx => _isOnline;
  
  @override
  Future<void> onInit() async {
    super.onInit();
    debugPrint('🌐 DioService 初始化开始...');
    
    try {
      await _initDio();
      _setupInterceptors();
      await _checkNetworkStatus();
      _isInitialized.value = true;
      
      debugPrint('✅ DioService 初始化完成');
    } catch (e) {
      debugPrint('❌ DioService 初始化失败: $e');
      rethrow;
    }
  }
  
  /// 初始化 Dio 实例
  Future<void> _initDio() async {
    try {
      final baseOptions = BaseOptions(
        connectTimeout: const Duration(milliseconds: defaultConnectTimeout),
        receiveTimeout: const Duration(milliseconds: defaultReceiveTimeout),
        sendTimeout: const Duration(milliseconds: defaultSendTimeout),
        headers: {
          httpHeaderContentType: httpContentTypeJson,
          httpHeaderAccept: httpAcceptJson,
          httpHeaderUserAgent: defaultUserAgent,
        },
        // 设置API服务器的基础URL
        baseUrl: defaultBaseUrl,
        validateStatus: (status) {
          // 接受所有状态码，由拦截器统一处理
          return status != null && status < httpStatusMaxValid;
        },
      );
      
      _dio = Dio(baseOptions);
      
      // 配置SSL证书处理（仅在debug模式下跳过证书验证）
      if (kDebugMode) {
        _configureDevelopmentSSL();
      }
      
      debugPrint('📡 Dio 实例创建成功');
    } catch (e) {
      debugPrint('❌ Dio 实例创建失败: $e');
      rethrow;
    }
  }
  
  /// 配置开发环境SSL证书处理
  void _configureDevelopmentSSL() {
    try {
      (_dio.httpClientAdapter as IOHttpClientAdapter).createHttpClient = () {
        final client = HttpClient();
        
        // 在开发环境中跳过SSL证书验证
        client.badCertificateCallback = (X509Certificate cert, String host, int port) {
          debugPrint('🔓 跳过SSL证书验证: $host:$port (开发环境)');
          return true; // 在开发环境中接受所有证书
        };
        
        return client;
      };
      
      debugPrint('🔓 已配置开发环境SSL证书跳过验证');
    } catch (e) {
      debugPrint('⚠️ SSL配置失败: $e');
    }
  }
  
  /// 设置拦截器
  void _setupInterceptors() {
    // 1. 请求拦截器 - 添加通用请求头
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) async {
        debugPrint('🔄 请求开始: ${options.method} ${options.uri}');
        
        // 添加请求ID用于追踪
        final requestId = DateTime.now().millisecondsSinceEpoch.toString();
        options.headers[httpHeaderRequestId] = requestId;
        
        // 在debug模式下打印请求详情
        if (kDebugMode) {
          debugPrint('📤 请求头: ${options.headers}');
          if (options.data != null) {
            debugPrint('📤 请求数据: ${options.data}');
          }
        }
        
        handler.next(options);
      },
      onResponse: (response, handler) {
        debugPrint('✅ 请求成功: ${response.statusCode} ${response.requestOptions.uri}');
        
        // 在debug模式下打印响应详情
        if (kDebugMode) {
          debugPrint('📥 响应数据: ${response.data}');
        }
        
        handler.next(response);
      },
      onError: (DioException error, handler) async {
        debugPrint('❌ 请求失败: ${error.requestOptions.method} ${error.requestOptions.uri}');
        debugPrint('❌ 错误信息: ${error.message}');
        debugPrint('❌ 错误类型: ${error.type}');
        
        // 处理网络错误
        final networkException = _processError(error);
        
        // 重新包装为DioException，但使用自定义异常作为error
        final processedError = DioException(
          requestOptions: error.requestOptions,
          response: error.response,
          type: error.type,
          error: networkException,
        );
        
        handler.next(processedError);
      },
    ));
    
    // 2. 日志拦截器 (仅在debug模式下)
    if (kDebugMode) {
      _dio.interceptors.add(LogInterceptor(
        requestBody: true,
        responseBody: true,
        requestHeader: false,
        responseHeader: false,
        error: true,
      ));
    }
    
    debugPrint('🔧 网络拦截器设置完成');
  }
  /// 处理网络错误，转换为自定义异常模型
  NetworkExceptionModel _processError(DioException error) {
    final requestPath = error.requestOptions.path;
    final requestMethod = error.requestOptions.method;
    
    switch (error.type) {
      case DioExceptionType.connectionTimeout:
        _isOnline.value = false;
        return NetworkExceptionModel.connectionTimeout(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: error,
        );
        
      case DioExceptionType.sendTimeout:
        return NetworkExceptionModel.requestTimeout(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: error,
        );
        
      case DioExceptionType.receiveTimeout:
        return NetworkExceptionModel.requestTimeout(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: error,
        );
        
      case DioExceptionType.badResponse:
        return _handleHttpError(error.response, requestPath, requestMethod, error);
        
      case DioExceptionType.cancel:
        return NetworkExceptionModel.cancelled(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: error,
        );
        
      case DioExceptionType.connectionError:
        _isOnline.value = false;
        return NetworkExceptionModel.connectionError(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: error,
        );
        
      case DioExceptionType.badCertificate:
        return NetworkExceptionModel(
          code: errorCodeSsl,
          message: 'SSL证书验证失败',
          type: NetworkErrorType.network,
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: error,
        );
        
      case DioExceptionType.unknown:
        return NetworkExceptionModel.unknown(
          message: '未知网络错误: ${error.message}',
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: error,
        );
    }
  }
  
  /// 处理HTTP状态码错误
  NetworkExceptionModel _handleHttpError(
    Response? response,
    String? requestPath,
    String? requestMethod,
    DioException originalException,
  ) {
    if (response == null) {
      return NetworkExceptionModel.serverError(
        requestPath: requestPath,
        requestMethod: requestMethod,
        originalException: originalException,
      );
    }
    
    final statusCode = response.statusCode ?? 0;
    
    // 使用工厂方法创建特定类型的异常
    switch (statusCode) {
      case 401:
        return NetworkExceptionModel.unauthorized(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: originalException,
        );
        
      case 403:
        return NetworkExceptionModel.forbidden(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: originalException,
        );
        
      case 404:
        return NetworkExceptionModel.notFound(
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: originalException,
        );
        
      default:
        // 对于其他HTTP状态码，使用通用的httpError工厂方法
        return NetworkExceptionModel.httpError(
          statusCode: statusCode,
          requestPath: requestPath,
          requestMethod: requestMethod,
          originalException: originalException,
        );
    }
  }
  
  /// 检查网络状态
  Future<void> _checkNetworkStatus() async {
    try {
      // 简单的网络检查，ping Google DNS
      await InternetAddress.lookup(googleDns);
      _isOnline.value = true;
      debugPrint('🌐 网络连接正常');
    } catch (e) {
      _isOnline.value = false;
      debugPrint('📶 网络连接异常: $e');
    }
  }
  
  // ==================== 公共HTTP方法 ====================
  
  /// GET请求
  Future<Response<T>> get<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      return await _dio.get<T>(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
        cancelToken: cancelToken,
        onReceiveProgress: onReceiveProgress,
      );
    } catch (e) {
      debugPrint('❌ GET请求失败: $path - $e');
      rethrow;
    }
  }
  
  /// POST请求
  Future<Response<T>> post<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      return await _dio.post<T>(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
        onReceiveProgress: onReceiveProgress,
      );
    } catch (e) {
      debugPrint('❌ POST请求失败: $path - $e');
      rethrow;
    }
  }
  
  /// PUT请求
  Future<Response<T>> put<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      return await _dio.put<T>(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
        onReceiveProgress: onReceiveProgress,
      );
    } catch (e) {
      debugPrint('❌ PUT请求失败: $path - $e');
      rethrow;
    }
  }
  
  /// DELETE请求
  Future<Response<T>> delete<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    try {
      return await _dio.delete<T>(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
        cancelToken: cancelToken,
      );
    } catch (e) {
      debugPrint('❌ DELETE请求失败: $path - $e');
      rethrow;
    }
  }
  
  /// PATCH请求
  Future<Response<T>> patch<T>(
    String path, {
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      return await _dio.patch<T>(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
        onReceiveProgress: onReceiveProgress,
      );
    } catch (e) {
      debugPrint('❌ PATCH请求失败: $path - $e');
      rethrow;
    }
  }
  
  // ==================== 文件操作方法 ====================
  
  /// 下载文件
  Future<Response> downloadFile(
    String url,
    String savePath, {
    ProgressCallback? onReceiveProgress,
    CancelToken? cancelToken,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    try {
      debugPrint('📥 开始下载文件: $url -> $savePath');
      
      return await _dio.download(
        url,
        savePath,
        onReceiveProgress: onReceiveProgress,
        cancelToken: cancelToken,
        queryParameters: queryParameters,
        options: options,
      );
    } catch (e) {
      debugPrint('❌ 文件下载失败: $url - $e');
      rethrow;
    }
  }
  
  /// 上传文件
  Future<Response<T>> uploadFile<T>(
    String path,
    String filePath, {
    String? fileName,
    String fileKey = 'file',
    Map<String, dynamic>? data,
    ProgressCallback? onSendProgress,
    CancelToken? cancelToken,
  }) async {
    try {
      debugPrint('📤 开始上传文件: $filePath -> $path');
      
      final formData = FormData.fromMap({
        ...?data,
        fileKey: await MultipartFile.fromFile(
          filePath,
          filename: fileName,
        ),
      });
      
      return await post<T>(
        path,
        data: formData,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
      );
    } catch (e) {
      debugPrint('❌ 文件上传失败: $filePath - $e');
      rethrow;
    }
  }
  
  /// 上传多个文件
  Future<Response<T>> uploadMultipleFiles<T>(
    String path,
    List<String> filePaths, {
    String fileKey = 'files',
    Map<String, dynamic>? data,
    ProgressCallback? onSendProgress,
    CancelToken? cancelToken,
  }) async {
    try {
      debugPrint('📤 开始上传多个文件: ${filePaths.length}个文件 -> $path');
      
      final files = <MultipartFile>[];
      for (String filePath in filePaths) {
        files.add(await MultipartFile.fromFile(filePath));
      }
      
      final formData = FormData.fromMap({
        ...?data,
        fileKey: files,
      });
      
      return await post<T>(
        path,
        data: formData,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
      );
    } catch (e) {
      debugPrint('❌ 多文件上传失败: $e');
      rethrow;
    }
  }
  
  // ==================== 工具方法 ====================
  
  /// 设置Base URL
  void setBaseUrl(String baseUrl) {
    _dio.options.baseUrl = baseUrl;
    debugPrint('🔧 设置Base URL: $baseUrl');
  }
  
  /// 添加公共请求头
  void addHeaders(Map<String, dynamic> headers) {
    _dio.options.headers.addAll(headers);
    debugPrint('🔧 添加公共请求头: $headers');
  }
  
  /// 移除请求头
  void removeHeader(String key) {
    _dio.options.headers.remove(key);
    debugPrint('🔧 移除请求头: $key');
  }
  
  /// 设置超时时间
  void setTimeout({
    Duration? connectTimeout,
    Duration? receiveTimeout,
    Duration? sendTimeout,
  }) {
    if (connectTimeout != null) {
      _dio.options.connectTimeout = connectTimeout;
    }
    if (receiveTimeout != null) {
      _dio.options.receiveTimeout = receiveTimeout;
    }
    if (sendTimeout != null) {
      _dio.options.sendTimeout = sendTimeout;
    }
    debugPrint('🔧 设置超时时间: connect=$connectTimeout, receive=$receiveTimeout, send=$sendTimeout');
  }
  
  /// 添加拦截器
  void addInterceptor(Interceptor interceptor) {
    _dio.interceptors.add(interceptor);
    debugPrint('🔧 添加拦截器: ${interceptor.runtimeType}');
  }
  
  /// 移除拦截器
  void removeInterceptor(Interceptor interceptor) {
    _dio.interceptors.remove(interceptor);
    debugPrint('🔧 移除拦截器: ${interceptor.runtimeType}');
  }
  
  /// 清除所有拦截器
  void clearInterceptors() {
    _dio.interceptors.clear();
    debugPrint('🔧 清除所有拦截器');
  }
  
  /// 创建取消token
  CancelToken createCancelToken() {
    return CancelToken();
  }
  
  /// 重新检查网络状态
  Future<void> checkNetworkStatus() async {
    await _checkNetworkStatus();
  }
  
  @override
  void onClose() {
    debugPrint('🧹 DioService 正在清理...');
    _dio.close();
    super.onClose();
  }
}
